package com.csthink.common.application;

import com.csthink.common.infrastructure.enums.ErrorEnum;
import com.csthink.common.infrastructure.exception.BaseException;
import com.csthink.common.infrastructure.util.ErrorMessageUtil;
import com.csthink.common.infrastructure.util.Jackson2Util;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 统一响应体
 *
 * @author <a href="mailto:security.2009@live.cn">Mars</a>
 * @since 2023-09-09
 */
@Getter
@Setter
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseWrapper<T> {

    private boolean status = true;
    private String errorCode;
    private String errorMessage;

    private T result;

    public static <T> ResponseWrapper<T> success() {
        ResponseWrapper<T> response = new ResponseWrapper<>();
        response.setStatus(true);
        return response;
    }

    public static <T> ResponseWrapper<T> success(T result) {
        ResponseWrapper<T> response = new ResponseWrapper<>();
        response.setStatus(true);
        response.setResult(result);
        return response;
    }

    public static <T> ResponseWrapper<T> error(final ErrorEnum errorEnum, final String errorMessage, final T result) {
        ResponseWrapper<T> response = new ResponseWrapper<>();
        response.setStatus(false);
        response.setErrorCode(String.valueOf(errorEnum.getErrorCode()));
        response.setErrorMessage(errorMessage);
        response.setResult(result);
        return response;
    }

    public static <T> ResponseWrapper<T> error(final ErrorEnum errorEnum, final String errorMessage) {
        ResponseWrapper<T> response = new ResponseWrapper<>();
        response.setStatus(false);
        response.setErrorCode(String.valueOf(errorEnum.getErrorCode()));
        response.setErrorMessage(errorMessage);
        return response;
    }

    public static <T> ResponseWrapper<T> error(final ErrorEnum errorEnum, final T result) {
        ResponseWrapper<T> response = new ResponseWrapper<>();
        response.setStatus(false);
        response.setErrorCode(String.valueOf(errorEnum.getErrorCode()));
        response.setErrorMessage(ErrorMessageUtil.getMessage(errorEnum.getErrorCode()));
        response.setResult(result);
        return response;
    }

    public static <T> ResponseWrapper<T> error(final ErrorEnum errorEnum) {
        ResponseWrapper<T> response = new ResponseWrapper<>();
        response.setStatus(false);
        response.setErrorCode(String.valueOf(errorEnum.getErrorCode()));
        response.setErrorMessage(ErrorMessageUtil.getMessage(errorEnum.getErrorCode()));
        return response;
    }

    public static <T> void responseError(ErrorEnum errorEnum, String errorMessage, HttpServletResponse response) {
        try {
            ResponseWrapper<T> responseWrapper = ResponseWrapper.error(errorEnum.getErrorCode(), errorMessage);
            String strResponseWrapper = Jackson2Util.toJson(responseWrapper);
            response.setHeader("Content-Type", "application/json");
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(strResponseWrapper);
        } catch (IOException e) {
            throw new BaseException(ErrorEnum.UNKNOWN_ERROR);
        }
    }

    /**
     * Must be private, error code should be maintained in ErrorEnum
     */
    private static <T> ResponseWrapper<T> error(final int errorCode, final String errorMessage) {
        ResponseWrapper<T> response = new ResponseWrapper<>();
        response.setStatus(false);
        response.setErrorCode(String.valueOf(errorCode));
        response.setErrorMessage(errorMessage);
        return response;
    }
}
